package com.ezlcp.form.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ezlcp.commons.base.db.BaseService;
import com.ezlcp.commons.base.entity.JsonPageResult;
import com.ezlcp.commons.base.entity.JsonResult;
import com.ezlcp.commons.base.search.QueryFilter;
import com.ezlcp.commons.constant.DataTypeEnum;
import com.ezlcp.commons.tool.StringUtils;
import com.ezlcp.commons.utils.ContextUtil;
import com.ezlcp.form.entity.Entity;
import com.ezlcp.form.entity.EntityCol;
import com.ezlcp.form.service.EntityServiceImpl;
import com.ezlcp.form.web.BaseController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/ezlcp/form/entity")
@Tag(name = "数据库中表的定义")
public class EntityController extends BaseController<Entity> {
    @Resource
    EntityServiceImpl entityService;

    @Operation(summary = "获取自定义实体固定字段", description = "不能被删除和修改")
    @PostMapping("getFixedCols")
    public JsonResult getFixedCols() {
        var result = JsonResult.Success("common.handleSuccess");
        result.setData(entityService.getFixedCols());
        return result;
    }

    @Operation(summary = "获取实体数据类型")
    @PostMapping("getDataTypes")
    public JsonResult getDataTypes() {
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        var types = DataTypeEnum.values();
        JSONArray array = new JSONArray();
        for (var type : types) {
            array.add(type.toJsonObject());
        }
        result.setData(array);
        return result;
    }

    @Operation(summary = "从数据库中的已存在的表或视图逆向生成实体")
    @PostMapping("createFromDB")
    public JsonResult createFromDB(@Parameter(description = "模块ID") @RequestParam(value = "moduleId") String moduleId,
                                   @Parameter(description = "数据源ID") @RequestParam(value = "dsId") String dsId,
                                   @Parameter(description = "表名") @RequestParam("tableName") String tableName) {
        if (StringUtils.isEmpty(moduleId) || StringUtils.isEmpty(dsId) || StringUtils.isEmpty(tableName)) {
            return JsonResult.Fail("common.paramError");
        }
        return entityService.createFromDB(dsId, tableName, moduleId);
    }

    @Operation(summary = "检查物理表名是否重复")
    @PostMapping("checkTableName")
    public JsonResult checkTableName(@Parameter(description = "表名") @RequestParam("tableName") String tableName,
                                     @Parameter(description = "实体ID") @RequestParam(value = "entId", required = false) String entId,
                                     @Parameter(description = "数据源ID") @RequestParam(value = "dsId", required = false) String dsId) {
        boolean repeat = entityService.checkTableName(tableName, entId, dsId);
        if (repeat) {
            //物理表名重复，请检查
            return JsonResult.Fail("entity.tableNameRepeat");
        }
        return JsonResult.Success("common.handleSuccess");
    }

    @Override
    public JsonResult del(@RequestParam(value = "id") String id) {
        return JsonResult.Fail("common.apiClose");
    }

    @Operation(summary = "根据主键ID删除记录")
    @PostMapping("delete")
    public JsonResult delete(@Parameter(description = "主键Id") @RequestParam(value = "id") String id,
                             @Parameter(description = "是否删除物理表") @RequestParam(value = "delTable") Boolean delTable) {
        if (StringUtils.isEmpty(id)) {
            return JsonResult.Fail("common.paramError");
        }
        //TODO 判断是否被自定义表单引用
        entityService.delEntity(id, delTable);
        JsonResult result = JsonResult.Success("common.delSuccess");
        logService.saveSystemLog(getComment(), "delete", id, "");
        return result;
    }

    @Operation(summary = "发布实体", description = "如果需要，会在数据库中建表")
    @PostMapping("/publish")
    public JsonResult publish(@Parameter(description = "主键Id") @RequestParam(value = "entId") String entId) {
        if (StringUtils.isEmpty(entId)) {
            return JsonResult.Fail("common.paramError");
        }
        return entityService.publishEntity(entId);
    }

    @Operation(summary = "保存实体信息")
    @PostMapping("/saveEnt")
    public JsonResult saveEnt(@RequestBody JSONObject data) {
        var entity = data.getObject("entity", Entity.class);
        if (entity == null || entity.getCols() == null || entity.getCols().isEmpty()) {
            return JsonResult.Fail("common.paramError");
        }
        boolean repeat = entityService.checkTableName(entity.getTableName(), entity.getEntId(), entity.getDsId());
        if (repeat) {
            //物理表名重复，请检查
            return JsonResult.Fail("entity.tableNameRepeat");
        }
        String delIds = data.getString("deleteIds");
        String msg = entityService.saveEntity(entity, delIds);
        if (StringUtils.isNotEmpty(msg)) {
            return JsonResult.Fail(msg);
        }
        logService.saveSystemLog(getComment(), "save", null, JSON.toJSONString(data));
        return JsonResult.Success("common.handleSuccess");
    }

    @Operation(summary = "选择关联实体", description = "不能与自己关联")
    @PostMapping("/selectEntity")
    public JsonResult selectEntity(@Parameter(description = "当前实体ID") @RequestParam(value = "entId",required = false) String entId){
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        result.setData(entityService.selectEntity(entId));
        return result;
    }

    @Operation(summary = "查询某模块下的实体")
    @PostMapping("/selectByModuleId")
    public JsonResult selectByModuleId(@Parameter(description = "模块ID") @RequestParam(value = "moduleId") String moduleId){
        if (StringUtils.isEmpty(moduleId)) {
            return JsonResult.Fail("common.paramError");
        }
        JsonResult result = JsonResult.getSuccessResult("common.handleSuccess");
        result.setData(entityService.selectByModuleId(moduleId));
        return result;
    }

    @Operation(summary = "查询实体表的所有字段")
    @GetMapping("/getFields")
    public List<EntityCol> getFields(@Parameter(description = "实体ID") @RequestParam(value = "entId") String entId ){
        if (StringUtils.isEmpty(entId)) {
            return new ArrayList<>();
        }
        return entityService.getFields(entId);
    }

    @Override
    public JsonResult save(Entity entity, BindingResult validResult) throws Exception {
        return JsonResult.Fail("common.apiClose");
    }

    @Override
    public JsonPageResult getAll() {
        return JsonPageResult.getFail("common.apiClose");
    }

    @Override
    protected void handleFilter(QueryFilter filter) {
        String tenantId = ContextUtil.getCurrentTenantId();
        if (StringUtils.isNotEmpty(tenantId)) {
            filter.addQueryParam("Q_e.tenant_id_S_EQ", tenantId);
        }
    }

    @Override
    public BaseService getBaseService() {
        return entityService;
    }

    @Override
    public String getComment() {
        return "实体管理";
    }
}